package edu.ustb.efws.meter.controller;

import edu.ustb.efws.controller.vo.ResultVo;
import edu.ustb.efws.meter.domain.Meter;
import edu.ustb.efws.meter.service.MeterService;
import edu.ustb.efws.pipeline.collect.cache.RiskCache;
import edu.ustb.efws.pipeline.domain.RiskLog;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.Duration;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 测量值接口
 *
 * @author TS Group
 */
@RestController
@RequestMapping("/meter")
@Api(value = "/meter", tags = "测量值接口")
public class MeterController {
    //最大等待数据时间
    private static final long MAX_WAIT = Duration.ofMinutes(5).toMillis();

    private final MeterService service;

    @Autowired
    public MeterController(MeterService service) {
        this.service = service;
    }

    @GetMapping(value = "/day", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("查询天数据")
    public ResultVo<List<Meter>> queryDay(@RequestParam("positionId")int positionId,
                                          @RequestParam("year") int year,
                                          @RequestParam("month") int month,
                                          @RequestParam("day") int day){

        int m = year * 100 + month;
        if(positionId < 50){
            return ResultVo.success(service.queryDay(positionId, m, day));
        }

        int pId = positionId > 100? positionId / 10: positionId;
        if(pId < 53){
            return ResultVo.success(service.queryDay(50 * (positionId / pId), m, day));
        }
        return ResultVo.success(service.queryDay(53 * (positionId / pId), m, day));
    }

    @GetMapping(value = "/month", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("查询月数据")
    public ResultVo<List<Meter>> queryMonth(@RequestParam("positionId")int positionId,
                                          @RequestParam("year") int year,
                                          @RequestParam("month") int month){

        int m = year * 100 + month;
        if(positionId < 50){
            return ResultVo.success(service.queryMonth(positionId, m));
        }

        int pId = positionId > 100? positionId / 10: positionId;
        if(pId < 53){
            return ResultVo.success(service.queryMonth(50 * (positionId / pId), m));
        }
        return ResultVo.success(service.queryMonth(53 * (positionId / pId), m));
    }

    @GetMapping(value = "/year", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("查询年数据")
    public ResultVo<List<Meter>> queryYear(@RequestParam("positionId")int positionId,
                                            @RequestParam("year") int year){

        if(positionId < 50){
            return ResultVo.success(service.queryYear(positionId, year));
        }

        int pId = positionId > 100? positionId / 10: positionId;

        if(pId < 53){
            return ResultVo.success(service.queryYear(50 * (positionId / pId), year));
        }

        return ResultVo.success(service.queryYear(53 * (positionId / pId), year));
    }

    @GetMapping(value = "risk", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation("查询当前风险值")
    public ResultVo<List<RiskLog>> queryRisk(@RequestParam(value = "positionIds", required = false)List<Integer> positionIds){

        RiskCache cache = RiskCache.INSTANCE;
        long now = System.currentTimeMillis();

        List<RiskCache.RiskLogTimestamp> list = Objects.isNull(positionIds) || positionIds.isEmpty()? cache.all(): cache.get(positionIds);

        List<RiskLog> logs = list.stream()
                .filter(e -> {
                    boolean expired = now - e.getTimestamp() > MAX_WAIT;
                    if(expired){
                        cache.remove(e.getRiskLog().getPositionId());
                    }
                    return !expired;
                })
                .map(RiskCache.RiskLogTimestamp::getRiskLog)
                .collect(Collectors.toList());

        return ResultVo.success(logs);
    }
}
